package com.jiangyao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiangyao.common.exception.ServerException;
import com.jiangyao.dao.*;
import com.jiangyao.model.dto.SubmitCourseQuestionDTO;
import com.jiangyao.model.dto.SubmitPublicCourseQuestionDTO;
import com.jiangyao.model.dto.SubmitQuestionDTO;
import com.jiangyao.model.dto.backend.QuestionChooseDTO;
import com.jiangyao.model.dto.backend.QuestionDTO;
import com.jiangyao.model.dto.backend.QuestionDetailDTO;
import com.jiangyao.model.dto.backend.QuestionItemDTO;
import com.jiangyao.model.dto.backend.QuestionItemDelDTO;
import com.jiangyao.model.dto.backend.QuestionListPageDTO;
import com.jiangyao.model.entity.*;
import com.jiangyao.model.vo.AnAuditionQuestionVo;
import com.jiangyao.model.vo.QuestionDetailVO;
import com.jiangyao.model.vo.SubmitQuestionVo;
import com.jiangyao.model.vo.backend.QuestionItemVO;
import com.jiangyao.model.vo.backend.QuestionListVO;
import com.jiangyao.service.QuestionService;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 试题信息表 服务实现类
 * </p>
 *
 * @author zhoushuangxiang
 * @since 2020-08-18
 */
@Service
public class QuestionServiceImpl extends BaseServiceImpl<IQuestionDao, Question> implements QuestionService {

    @Autowired
    private IQuestionDao iQuestionDao;

    @Autowired
    private DozerBeanMapper dozerBeanMapper;

    @Autowired
    private IQuestionDetailDao iQuestionDetailDao;

    @Autowired
    private IQuestionChooseDao iQuestionChooseDao;

    @Autowired
    private IUserAnswerLogDao iUserAnswerLogDao;

    @Autowired
    private IUserAnswerDao iUserAnswerDao;

    @Override
    public AnAuditionQuestionVo getQuestion(String questionId) throws ServerException{
        QueryWrapper<Question> questionQueryWrapper = new QueryWrapper<>();
        questionQueryWrapper.eq("question_id",questionId).eq("status",1);
        Question question = iQuestionDao.selectOne(questionQueryWrapper);
        if(question == null){
            throw new ServerException(500,"没有找到对应试题");
        }
        AnAuditionQuestionVo questionVo = dozerBeanMapper.map(question, AnAuditionQuestionVo.class);
        List<QuestionDetailVO> questionDetailList = iQuestionDetailDao.selectDetailList(questionId);
        for (QuestionDetailVO questionDetailVO : questionDetailList) {
            QueryWrapper<QuestionChoose> questionChooseQueryWrapper = new QueryWrapper<>();
            questionChooseQueryWrapper.eq("question_id",questionId).eq("detail_id",questionDetailVO.getDetailId());
            List<QuestionChoose> questionChooses = iQuestionChooseDao.selectList(questionChooseQueryWrapper);
            questionDetailVO.setQuestionChooseList(questionChooses);
        }
        questionVo.setStartTime(new Date());
        questionVo.setQuestionDetailList(questionDetailList);
        return questionVo;
    }

    @Override
    public SubmitQuestionVo submitQuestion(SubmitQuestionDTO submitQuestionDTO) {
        //计算答题时间
        long time = new Date().getTime() - submitQuestionDTO.getStartTime().getTime();
        String questionTime="";
        long days = time / (1000 * 60 * 60 * 24);
        long hours = (time-days*(1000 * 60 * 60 * 24))/(1000* 60 * 60); //获取时
        long minutes = (time-days*(1000 * 60 * 60 * 24)-hours*(1000* 60 * 60))/(1000* 60);  //获取分钟
        long s=(time/1000-days*24*60*60-hours*60*60-minutes*60);//获取秒
        if(days > 0){
            questionTime = days+"天"+hours+"小时"+minutes+"分钟"+s+"秒";
        }else if(hours > 0){
            questionTime = hours+"小时"+minutes+"分钟"+s+"秒";
        }else if(minutes > 0){
            questionTime = minutes+"分钟"+s+"秒";
        }else {
            questionTime = s+"秒";
        }
        QueryWrapper<Question> questionQueryWrapper = new QueryWrapper<>();
        questionQueryWrapper.eq("question_id",submitQuestionDTO.getQuestionId()).eq("status",1);

        Question question = iQuestionDao.selectOne(questionQueryWrapper);
        if(question == null) {
            throw new ServerException(500,"您所提交的试题题库中不存在");
        }
        Integer totalScore = 0;
        //遍历提交答案的map
        int size = submitQuestionDTO.getSubmitQuestionMap().size();
        if (size == 0){
            throw new ServerException(500,"不能提交空卷");
        }
        for (Map.Entry<String, String> entry : submitQuestionDTO.getSubmitQuestionMap().entrySet()) {
            QueryWrapper<QuestionChoose> questionChooseQueryWrapper = new QueryWrapper<>();
            questionChooseQueryWrapper.eq("question_id",submitQuestionDTO.getQuestionId())
                    .eq("detail_id",entry.getKey())
                    .eq("choose",entry.getValue());
            QuestionChoose questionChoose = iQuestionChooseDao.selectOne(questionChooseQueryWrapper);
            if(questionChoose != null){
                //如果正确
                if(questionChoose.getIsAnswer() == 1){
                    QueryWrapper<QuestionDetail> questionDetailQueryWrapper = new QueryWrapper<>();
                    questionDetailQueryWrapper.eq("detail_id",entry.getKey());
                    QuestionDetail questionDetail = iQuestionDetailDao.selectOne(questionDetailQueryWrapper);
                    totalScore += questionDetail.getScore();
                }
            }
        }
        SubmitQuestionVo submitQuestionVo = new SubmitQuestionVo();
        submitQuestionVo.setTotalScore(totalScore);
        submitQuestionVo.setEndTime(questionTime);
        if(totalScore >= question.getQuestionScore()){
            submitQuestionVo.setIsPass(1);
        }
        return submitQuestionVo;
    }


    @Override
    public  SubmitQuestionVo submitCourseQuestion(SubmitCourseQuestionDTO submitCourseQuestionDTO){
        SubmitQuestionDTO submitQuestionDTO = dozerBeanMapper.map(submitCourseQuestionDTO, SubmitQuestionDTO.class);
        SubmitQuestionVo submitQuestionVo = submitQuestion(submitQuestionDTO);
        if(submitQuestionVo!=null){
            UserAnswerLog userAnswerLog = dozerBeanMapper.map(submitCourseQuestionDTO, UserAnswerLog.class);
           userAnswerLog.setUserId(getLoginApiUserId());
            userAnswerLog.setChapterId(submitCourseQuestionDTO.getType()==2?submitCourseQuestionDTO.getReleteId():0);
            userAnswerLog.setCoursewareId(submitCourseQuestionDTO.getType()==1?submitCourseQuestionDTO.getReleteId():0);
            userAnswerLog.setEndTime(new Date());
            userAnswerLog.setAnswerScore(submitQuestionVo.getTotalScore());
            iUserAnswerLogDao.insert(userAnswerLog);

            QueryWrapper<UserAnswer> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("clsub_id",submitCourseQuestionDTO.getClsubId());
            queryWrapper.eq("chapter_id",submitCourseQuestionDTO.getType()==2?submitCourseQuestionDTO.getReleteId():0);
            queryWrapper.eq("courseware_id",submitCourseQuestionDTO.getType()==1?submitCourseQuestionDTO.getReleteId():0);
            queryWrapper.eq("type",submitCourseQuestionDTO.getType());
            queryWrapper.last("limit 1");
            UserAnswer userAnswer1 = iUserAnswerDao.selectOne(queryWrapper);

            if(userAnswer1==null){
                UserAnswer userAnswer = dozerBeanMapper.map(submitCourseQuestionDTO, UserAnswer.class);
                userAnswer.setUserId(getLoginApiUserId());
                userAnswer.setChapterId(submitCourseQuestionDTO.getType()==2?submitCourseQuestionDTO.getReleteId():0);
                userAnswer.setCoursewareId(submitCourseQuestionDTO.getType()==1?submitCourseQuestionDTO.getReleteId():0);
                userAnswer.setEndTime(new Date());
                userAnswer.setAnswerScore(submitQuestionVo.getTotalScore());
                iUserAnswerDao.insert(userAnswer);
            }else {
                QueryWrapper<UserAnswerLog> userAnswerLogQueryWrapper=new QueryWrapper<>();

                Integer maxScore = iUserAnswerDao.getMaxScore(getLoginApiUserId(),submitCourseQuestionDTO);


                UpdateWrapper<UserAnswer> userAnswerUpdateWrapper=new UpdateWrapper<>();
                userAnswerUpdateWrapper.eq("answer_id",userAnswer1.getAnswerId());

                //userAnswerUpdateWrapper.set("answer_score",maxScore==0?maxScore:submitQuestionVo.getTotalScore());
                userAnswerUpdateWrapper.set("answer_score",maxScore);
                iUserAnswerDao.update(null,userAnswerUpdateWrapper);
            }
        }
        return submitQuestionVo;
    }


    @Override
    public  SubmitQuestionVo submitPublicCourseQuestion(SubmitPublicCourseQuestionDTO submitCourseQuestionDTO){
        SubmitQuestionDTO submitQuestionDTO = dozerBeanMapper.map(submitCourseQuestionDTO, SubmitQuestionDTO.class);
        SubmitQuestionVo submitQuestionVo = submitQuestion(submitQuestionDTO);
        if(submitQuestionVo!=null){
            UserAnswerLog userAnswerLog = dozerBeanMapper.map(submitCourseQuestionDTO, UserAnswerLog.class);
            userAnswerLog.setUserId(getLoginApiUserId());
            //userAnswerLog.setUserId(1);
            userAnswerLog.setChapterId(submitCourseQuestionDTO.getType()==2?submitCourseQuestionDTO.getReleteId():0);
            userAnswerLog.setCoursewareId(submitCourseQuestionDTO.getType()==1?submitCourseQuestionDTO.getReleteId():0);
            userAnswerLog.setEndTime(new Date());
            userAnswerLog.setAnswerScore(submitQuestionVo.getTotalScore());
            iUserAnswerLogDao.insert(userAnswerLog);

            QueryWrapper<UserAnswer> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("subject_id",submitCourseQuestionDTO.getSubjectId());
            queryWrapper.eq("chapter_id",submitCourseQuestionDTO.getType()==2?submitCourseQuestionDTO.getReleteId():0);
            queryWrapper.eq("courseware_id",submitCourseQuestionDTO.getType()==1?submitCourseQuestionDTO.getReleteId():0);
            queryWrapper.eq("type",submitCourseQuestionDTO.getType());
            queryWrapper.last("limit 1");
            UserAnswer userAnswer1 = iUserAnswerDao.selectOne(queryWrapper);

            if(userAnswer1==null){
                UserAnswer userAnswer = dozerBeanMapper.map(submitCourseQuestionDTO, UserAnswer.class);
                userAnswer.setUserId(getLoginApiUserId());
                //userAnswer.setUserId(1);
                userAnswer.setChapterId(submitCourseQuestionDTO.getType()==2?submitCourseQuestionDTO.getReleteId():0);
                userAnswer.setCoursewareId(submitCourseQuestionDTO.getType()==1?submitCourseQuestionDTO.getReleteId():0);
                userAnswer.setEndTime(new Date());
                userAnswer.setAnswerScore(submitQuestionVo.getTotalScore());
                iUserAnswerDao.insert(userAnswer);
            }else {
                QueryWrapper<UserAnswerLog> userAnswerLogQueryWrapper=new QueryWrapper<>();

                Integer maxScore = iUserAnswerDao.getPublicMaxScore(getLoginApiUserId(),submitCourseQuestionDTO);


                UpdateWrapper<UserAnswer> userAnswerUpdateWrapper=new UpdateWrapper<>();
                userAnswerUpdateWrapper.eq("answer_id",userAnswer1.getAnswerId());

                //userAnswerUpdateWrapper.set("answer_score",maxScore==0?maxScore:submitQuestionVo.getTotalScore());
                userAnswerUpdateWrapper.set("answer_score",maxScore);
                iUserAnswerDao.update(null,userAnswerUpdateWrapper);
            }
        }
        return submitQuestionVo;
    }


    @Override
    public Page<QuestionListVO> getListPage(QuestionListPageDTO listPageDTO) {
        Page<QuestionListVO> page = new Page<>(listPageDTO.getPageNo(), listPageDTO.getPageSize());
        iQuestionDao.getListPage(page, listPageDTO);
        return page;
    }

    @Override
    public void add(QuestionDTO questionDTO) {
        Question question = dozerBeanMapper.map(questionDTO, Question.class);
        question.setQuestionId(null);
        question.setStatus(1);
        question.setCreateTime(new Date());
        question.setCreateAdminId(getLoginAdminUserId());
        this.save(question);
    }

    @Override
    public void edit(QuestionDTO questionDTO) {
        Question question = this.getById(questionDTO.getQuestionId());
        if (question == null) {
            throw new ServerException(100, "试题不存在");
        }
        UpdateWrapper<Question> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("question_id", questionDTO.getQuestionId());
        updateWrapper.set("category_id", questionDTO.getCategoryId());
        updateWrapper.set("question_name", questionDTO.getQuestionName());
        updateWrapper.set("question_score", questionDTO.getQuestionScore());
        updateWrapper.set("update_time", new Date());
        updateWrapper.set("update_admin_id", getLoginAdminUserId());
        this.update(updateWrapper);
    }

    @Override
    public void editStatus(QuestionDTO questionDTO) {
        if (CollectionUtils.isEmpty(questionDTO.getQuestionIdList())) {
            return;
        }
        UpdateWrapper<Question> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("question_id", questionDTO.getQuestionIdList());
        updateWrapper.set("status", questionDTO.getStatus() == null ? 1 : questionDTO.getStatus());
        updateWrapper.set("update_time", new Date());
        updateWrapper.set("update_admin_id", getLoginAdminUserId());
        this.update(updateWrapper);
    }

	@Override
	public com.jiangyao.model.vo.backend.QuestionDetailVO getItemList(QuestionDTO questionDTO) {
        Question question = this.getById(questionDTO.getQuestionId());
        if (question == null) {
            throw new ServerException(100, "试题不存在");
        }
        com.jiangyao.model.vo.backend.QuestionDetailVO questionDetailVO = new com.jiangyao.model.vo.backend.QuestionDetailVO();
        questionDetailVO.setQuestionId(question.getQuestionId());
        questionDetailVO.setQuestionName(question.getQuestionName());
        // 获取题目列表与题目选项
        List<QuestionItemVO> itemVOList = iQuestionDetailDao.getListAndChooseList(question.getQuestionId());
        questionDetailVO.setItemList(itemVOList);

        return questionDetailVO;

	}

	@Transactional(rollbackFor = Exception.class)
    @Override
    public void updateItemList(QuestionDetailDTO detailDTO) {
        Question question = this.getById(detailDTO.getQuestionId());
        if (question == null) {
            throw new ServerException(100, "试题不存在");
        }
        if (CollectionUtils.isEmpty(detailDTO.getItemList())) {
            return;
        }

        // 新建编辑题目
        for (QuestionItemDTO itemDTO : detailDTO.getItemList()) {
            updateQuestionItem(question.getQuestionId(), itemDTO);
        }
        // 修改试题修改时间
        UpdateWrapper<Question> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("question_id", question.getQuestionId());
        updateWrapper.set("update_time", new Date());
        updateWrapper.set("update_admin_id", getLoginAdminUserId());
        this.update(updateWrapper);
    }

    /**
     * 新建编辑题目
     *
     * @param questionId 试题id
     * @param itemDTO    试题题目
     */
    private void updateQuestionItem(Integer questionId, QuestionItemDTO itemDTO) {

        QuestionDetail questionDetail = dozerBeanMapper.map(itemDTO, QuestionDetail.class);
        // 新增试题题目
        if (questionDetail.getDetailId() == null || questionDetail.getDetailId() == 0) {
            questionDetail.setDetailId(null);
            questionDetail.setQuestionId(questionId);
            questionDetail.setStatus(1);
            iQuestionDetailDao.insert(questionDetail);
        } else {
            // 编辑试题题目
            UpdateWrapper<QuestionDetail> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("detail_id", questionDetail.getDetailId());
            updateWrapper.eq("question_id", questionId);
            updateWrapper.set("question_type", questionDetail.getQuestionType());
            updateWrapper.set("question_title", questionDetail.getQuestionTitle());
            updateWrapper.set("score", questionDetail.getScore());
            updateWrapper.set("sort_order", questionDetail.getSortOrder());
            iQuestionDetailDao.update(null, updateWrapper);
        }

        if (CollectionUtils.isEmpty(itemDTO.getChooseList())) {
            return;
        }
        // 新建编辑题目选项
        for (QuestionChooseDTO chooseDTO : itemDTO.getChooseList()) {
            updateQuestionItem(questionId, questionDetail.getDetailId(), chooseDTO);
        }

    }

    /**
     * 新建编辑题目选项
     *
     * @param questionId 试题id
     * @param detailId   试题题目id
     * @param chooseDTO  试题题目选项
     */
    private void updateQuestionItem(Integer questionId, Integer detailId, QuestionChooseDTO chooseDTO) {
        QuestionChoose questionChoose = dozerBeanMapper.map(chooseDTO, QuestionChoose.class);
        questionChoose.setId(chooseDTO.getChooseId());
        // 新增试题题目选项
        if (questionChoose.getId() == null || questionChoose.getId() == 0) {
            questionChoose.setQuestionId(questionId);
            questionChoose.setDetailId(detailId);
            questionChoose.setId(null);
            iQuestionChooseDao.insert(questionChoose);
        } else {
            //编辑试题题目选项
            UpdateWrapper<QuestionChoose> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("detail_id", detailId);
            updateWrapper.eq("question_id", questionId);
            updateWrapper.eq("id", questionChoose.getId());
            updateWrapper.set("choose", questionChoose.getChoose());
            updateWrapper.set("solution", questionChoose.getSolution());
            updateWrapper.set("is_answer", questionChoose.getIsAnswer());
            iQuestionChooseDao.update(null, updateWrapper);
        }
    }

    @Override
    public void deleteItemList(QuestionItemDelDTO delDTO) {
        Question question = this.getById(delDTO.getQuestionId());
        if (question == null) {
            throw new ServerException(100, "试题不存在");
        }
        if (CollectionUtils.isEmpty(delDTO.getDetailIdList())) {
            return;
        }
        UpdateWrapper<QuestionDetail> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("question_id", delDTO.getQuestionId());
        updateWrapper.in("detail_id", delDTO.getDetailIdList());
        updateWrapper.set("status", 0);
        iQuestionDetailDao.update(null, updateWrapper);
        // 修改试题修改时间
        UpdateWrapper<Question> updateWrapper2 = new UpdateWrapper<>();
        updateWrapper2.eq("question_id", question.getQuestionId());
        updateWrapper2.set("update_time", new Date());
        updateWrapper2.set("update_admin_id", getLoginAdminUserId());
        this.update(updateWrapper2);
    }
}
